package com.carhailing.coupons.consumer;

import com.carhailing.common.domain.coupons.CouponUseRecord;
import com.carhailing.coupons.service.CouponScheduleService;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Gd
 * @package: com.carhailing.coupons.consumer
 * @Project: Online_Taxi_Project
 * @Name: ReceiveCouponsConsumer
 * @Date: 2024-7-28 19:12
 */
@Component
@Log4j2
public class ReceiveCouponsConsumer {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private CouponScheduleService couponScheduleService;

    @RabbitListener(queuesToDeclare = @Queue("user_coupons_revice"))
    public void receiveCouponsConsumer(CouponUseRecord couponUseRecord, Message message, Channel channel){

        log.info("异步发放优惠券...");
        try {
            // 获取消息id
            String messageId = message.getMessageProperties().getMessageId();
            // mq消息ID messageId 添加到 Redis  设置过期时间 避免重复消费
            String msg = redisTemplate.opsForValue().get("couponsId" + messageId);
            if(msg == null) {
                log.info("准备记录异步抢券记录...");
                couponScheduleService.insertCouponUseRecord(couponUseRecord);
                // 避免多次消费  给messageId设置有效时间  消费后校验
                redisTemplate.opsForValue().set("couponsId"+messageId,messageId,10, TimeUnit.MINUTES);
                // 确认消息
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        } catch (IOException e) {
            try {
                // 回退消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }
}
